package com.quyunshuo.module.home.activity.time

import android.content.Context
import android.content.res.Resources
import android.graphics.Color
import android.graphics.Typeface
import android.util.AttributeSet
import android.util.TypedValue
import android.view.LayoutInflater
import android.view.View
import android.widget.LinearLayout
import android.widget.TextView
import androidx.core.content.res.ResourcesCompat
import com.quyunshuo.module.home.R
import java.util.Calendar

// 定义时间单位标志位
private const val FLAG_SS = 0b1       // 秒标志位
private const val FLAG_MM = 0b10      // 分标志位
private const val FLAG_HH = 0b100     // 时标志位
private const val STYLE_HH_MM_SS = FLAG_HH or FLAG_MM or FLAG_SS  // 完整时间格式标志位

/**
 * 翻页时钟自定义视图
 *
 * 功能：
 * 1. 显示小时、分钟和秒的翻页时钟
 * 2. 支持自定义显示格式（只显示时分、只显示分秒等）
 * 3. 支持自定义文本大小、颜色、字体和动画时长
 * 4. 自动更新时间
 *
 * 使用方式：
 * 在XML布局中添加：
 * <com.quyunshuo.module.home.activity.time.FlipClockView
 *     android:layout_width="wrap_content"
 *     android:layout_height="wrap_content"
 *     app:flip_type="hh_mm_ss" />
 *
 * 支持的属性：
 * - flip_type: 显示格式 (hh_mm_ss, hh_mm, mm_ss)
 * - flip_textSize: 文本大小
 * - flip_textColor: 文本颜色
 * - flip_animationDuration: 翻页动画时长
 * - flip_textFont: 自定义字体
 */
open class FlipClockView @JvmOverloads constructor(
    context: Context,          // 上下文对象
    attrs: AttributeSet? = null, // XML属性集
    defStyleAttr: Int = 0       // 默认样式属性
) : LinearLayout(context, attrs, defStyleAttr),
    ResourceHelper {             // 实现资源帮助接口

    // 小时视图
    protected val hourView: FlipTextView
    // 分钟视图
    protected val minuteView: FlipTextView
    // 秒视图
    protected val secondView: FlipTextView
    // 时分分隔符
    protected var dividerHoursMinutes: TextView
    // 分秒分隔符
    protected var dividerMinutesSeconds: TextView

    // 是否正在更新时间
    private var isTicking: Boolean = false

    // 时钟显示类型（默认显示完整时间）
    var flipClockType: Int = STYLE_HH_MM_SS
        set(value) {
            field = value
            // 更新子视图可见性
            updateChildVisibility(value)
        }

    // 资源对象访问器
    override val res: Resources
        get() = resources

    init {
        // 设置水平方向布局
        orientation = HORIZONTAL

        // 从布局文件inflate视图
        @Suppress("LeakingThis")
        LayoutInflater.from(context).inflate(R.layout.merge_flip_clock, this, true)

        // 初始化视图组件
        hourView = findViewById(R.id.flipHourView)
        minuteView = findViewById(R.id.flipMinuteView)
        secondView = findViewById(R.id.flipSecondView)
        dividerHoursMinutes = findViewById(R.id.dividerHM)
        dividerMinutesSeconds = findViewById(R.id.dividerMS)

        // 解析XML属性
        parseAttributes(attrs, defStyleAttr)
    }

    /**
     * 解析XML属性
     *
     * @param attrs XML属性集
     * @param defStyleAttr 默认样式属性
     */
    private fun parseAttributes(attrs: AttributeSet?, defStyleAttr: Int) {
        if (attrs == null) {
            return
        }

        // 解析FlipTextView相关属性
        parseFlipTextAttrs(attrs, defStyleAttr)

        // 解析FlipClockView特有属性
        context.theme.obtainStyledAttributes(
            attrs,
            R.styleable.FlipClockView,
            defStyleAttr,
            0
        ).apply {
            try {
                // 获取显示类型属性
                flipClockType = getInt(R.styleable.FlipClockView_flip_type, STYLE_HH_MM_SS)
            } finally {
                // 回收资源
                recycle()
            }
        }
    }

    /**
     * 解析FlipTextView相关属性
     *
     * 这些属性会应用到所有时间单位视图和分隔符视图
     */
    private fun parseFlipTextAttrs(attrs: AttributeSet?, defStyleAttr: Int) {
        context.theme.obtainStyledAttributes(
            attrs,
            R.styleable.FlipTextView,
            defStyleAttr,
            0
        ).apply {
            try {
                // 获取文本大小（默认30sp）
                val textSize = getDimension(R.styleable.FlipTextView_flip_textSize, 30.sp)

                // 获取文本颜色（默认红色）
                val textColor = getColor(R.styleable.FlipTextView_flip_textColor, Color.RED)

                // 获取动画时长（默认400ms）
                val animationDuration =
                    getInt(R.styleable.FlipTextView_flip_animationDuration, 400).toLong()

                // 获取自定义字体
                val fontId = getResourceId(R.styleable.FlipTextView_flip_textFont, -1)
                var typeface: Typeface? = null
                if (fontId != -1) {
                    typeface = ResourcesCompat.getFont(context, fontId)
                }

                // 应用属性到所有时间单位视图
                for (v in listOf(hourView, minuteView, secondView)) {
                    v.textSize = textSize
                    v.textColor = Color.parseColor("#FFFFFFFF") // 固定为白色
                    v.animationDuration = animationDuration

                    if (typeface != null) v.typeface = typeface
                }

                // 应用属性到所有分隔符视图
                for (dividerView in listOf(dividerHoursMinutes, dividerMinutesSeconds)) {
                    dividerView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize)
                    dividerView.setTextColor(textColor)

                    if (typeface != null) dividerView.typeface = typeface
                }

            } finally {
                // 回收资源
                recycle()
            }
        }
    }

    /**
     * 根据显示类型更新子视图可见性
     *
     * @param value 显示类型标志位
     */
    private fun updateChildVisibility(value: Int) {
        // 解析各时间单位的可见性
        val hoursVisible = value and FLAG_HH != 0
        val minutesVisible = value and FLAG_MM != 0
        val secondsVisible = value and FLAG_SS != 0

        // 设置小时视图可见性
        hourView.visibility = if (hoursVisible) View.VISIBLE else View.GONE

        // 设置时分分隔符可见性（小时和分钟都可见时才显示）
        dividerHoursMinutes.visibility =
            if (hoursVisible && minutesVisible) View.VISIBLE else View.GONE

        // 设置分钟视图可见性
        minuteView.visibility = if (minutesVisible) View.VISIBLE else View.GONE

        // 设置分秒分隔符可见性（分钟和秒都可见时才显示）
        dividerMinutesSeconds.visibility =
            if (minutesVisible && secondsVisible) View.VISIBLE else View.GONE

        // 设置秒视图可见性
        secondView.visibility = if (secondsVisible) View.VISIBLE else View.GONE
    }

    /**
     * 当视图附加到窗口时调用
     * 开始更新时间
     */
    override fun onAttachedToWindow() {
        super.onAttachedToWindow()
        // 标记开始更新
        isTicking = true
        // 开始更新循环
        tick()
    }

    /**
     * 更新时间循环
     */
    protected fun tick() {
        // 如果停止更新则退出
        if (!isTicking) {
            return
        }

        // 更新时间文本
        onUpdateText()

        // 每秒更新一次
        postDelayed({ tick() }, 1000L)
    }

    /**
     * 更新时间文本内容
     */
    protected open fun onUpdateText() {
        // 获取当前时间
        val now = Calendar.getInstance()

        // 格式化时间字符串（24小时制）
        val hourText = "%02d".format(now.get(Calendar.HOUR_OF_DAY))
        val minuteText = "%02d".format(now.get(Calendar.MINUTE))
        val secondText = "%02d".format(now.get(Calendar.SECOND))

        // 更新各时间单位视图
        updateText(hourView, hourText)
        updateText(minuteView, minuteText)
        updateText(secondView, secondText)
    }

    /**
     * 更新单个时间单位视图
     *
     * @param flipTextView 目标视图
     * @param text 新时间文本
     */
    protected fun updateText(flipTextView: FlipTextView, text: String) {
        // 只有文本变化时才更新（避免不必要的动画）
        if (flipTextView.text != text) flipTextView.text = text
    }

    /**
     * 当视图从窗口分离时调用
     * 停止更新时间
     */
    override fun onDetachedFromWindow() {
        // 标记停止更新
        isTicking = false
        super.onDetachedFromWindow()
    }
}

/**
 * 扩展函数：将数值转换为sp单位
 */
val Number.sp: Float
    get() = TypedValue.applyDimension(
        TypedValue.COMPLEX_UNIT_SP,
        this.toFloat(),
        Resources.getSystem().displayMetrics
    )